package com.zw.mes.module.assemble.service;

import com.zw.mes.entity.asse.QrParse;
import com.zw.mes.entity.sys.User;
import com.zw.mes.module.assemble.entity.*;
import com.zw.mes.module.assemble.mapper.TestingMapper;
import com.zw.mes.module.assemble.model.TestModel;
import com.zw.mes.module.assemble.repository.*;
import com.zw.mes.module.prodtaskmanager.entity.ProdTas;
import com.zw.mes.module.prodtaskmanager.model.ProdTasModel;
import com.zw.mes.module.prodtaskmanager.service.ProdOrdService;
import com.zw.mes.module.system.service.LogService;
import com.zw.mes.util.BeanUtil;
import com.zw.mes.util.ShiroUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * @Description: 装配申请质检 业务
 * @Author: China.wsg
 * @Date: 2021/04/23 14:12
 */
@Service
@SuppressWarnings("all")
public class TestingService {

    @Autowired
    private TestingMapper testingMapper;
    @Autowired
    private AsseTransSheetRepository transSheetRepository;
    @Autowired
    private AsseTransCheckRepository transCheckRepository;
    @Autowired
    private AsseAssemblyRouteRepository assemblyRouteRepository;
    @Autowired
    private AsseAssemblySheetRepository assemblySheetRepository;
    @Autowired
    private AsseStoreRepository asseStoreRepository;
    @Autowired
    private LogService logService;
    @Autowired
    private AsseStoreRecordRepository storeRecordRepository;
    @Autowired
    private ProdOrdService prodOrdService;

    /**
     * 查询待质检列表
     *
     * @param barCode 派工单二维码 规则：生产令号|图号|部分ID|2
     * @return
     */
    public List<TestModel> findTestListByBarCode(String barCode) {
        if (barCode == null || barCode.equals("")) {
            barCode = "1|1|1|2";// 页面打开时避免，空指针崩溃特殊处理
        }
        QrParse parse = getQrParse(barCode);
        if (parse == null) return null;
        return testingMapper.findTestListByBarCode(parse);
    }

    /**
     * 字符串截取
     *
     * @param code
     * @return
     */
    private QrParse getQrParse(String code) {
        String[] arr = code.split("\\|");
        if (arr == null || arr.length < 4) {
            return null;
        }
        QrParse parse = new QrParse();
        parse.setProNo(arr[0]);
        parse.setDrawNo(arr[1]);
        parse.setPartId(arr[2]);
        parse.setCategory(arr[3]);
        return parse;
    }

    /**
     * 质检合格
     */
    @Transactional
    public int success(Integer id, Integer status, String result) {

        // 装配转序单表 与 装配质检表 存在一一对应的关系
        AsseTransSheet t = transSheetRepository.getOne(id);
        AsseTransCheck tc = transCheckRepository.findByTransId(t.getId());

        if (tc.getStatus() != 1) {
            return 0;
        }
        User u = ShiroUtils.getUser();
        tc.setCheckCode(u.getAccount());
        tc.setCheckName(u.getName());
        tc.setCheckTime(new Date());
        tc.setCheckDept(u.getBranchName());
        tc.setYield(status == 1 ? 0 : 1);
        tc.setResult(result);
        tc.setStatus(2);

        AsseAssemblyRoute cur = assemblyRouteRepository.getOne(t.getRouteId());
        AsseAssemblyRoute next = testingMapper.findNextRoute(cur);
        AsseAssemblySheet sheet = assemblySheetRepository.getOne(cur.getSheetId());
        int totalNum = sheet.getDrawNum() - sheet.getInvalid();
        cur.setCheckNum(cur.getCheckNum() + t.getNum());
        if (totalNum == cur.getCheckNum().intValue()) {
            cur.setStatus(4);
        } else {
            cur.setStatus(3);
        }
        if ("转储".equals(next.getRoute())) {
            //修改倒数第二道序为已接收
            tc.setStatus(3);
            //修改最后一道序的接收数量和状态
            next.setRecNum(next.getRecNum() + t.getNum());
            if (next.getRecNum() == totalNum) {
                next.setStatus(4);
            } else {
                next.setStatus(3);
            }
            testingMapper.updateRouteRecNum(next);

            // 判断 库存记录是否已经存在，存在更新，不存在插入（保证装配派工单与）
            AsseStore asseStore = asseStoreRepository.findBySheetId(sheet.getId());
            AsseStore store = new AsseStore();
            // 插入成品库
            if (asseStore != null) {
                BeanUtil.copy(asseStore, store);
                store.setSheetId(sheet.getId());
                store.setDrawNum(asseStore.getDrawNum() + t.getNum());
                store.setStoreAddr(t.getApplyDept());
                asseStoreRepository.save(store);
            } else {
                BeanUtil.copy(sheet, store);
                store.setSheetId(sheet.getId());
                store.setDrawNum(t.getNum());
                store.setStoreAddr(t.getApplyDept());
                store.setId(null);
                asseStoreRepository.save(store);
            }

            // 生产装配件入库记录
            AsseStoreRecord storeRecord = new AsseStoreRecord();
            storeRecord.setProdNo(store.getProdNo());
            storeRecord.setSpecial(store.getSpecial());
            storeRecord.setPartId(store.getPartId());
            storeRecord.setDrawName(store.getDrawName());
            storeRecord.setDrawNo(store.getDrawNo());
            storeRecord.setWeight(store.getDrawWeight());
            storeRecord.setDrawNum(t.getNum());
            storeRecord.setStoreType(1);
            storeRecord.setRecordType(1);
            storeRecord.setStoreAddr(store.getStoreAddr());
            storeRecord.setStorageRegisterCode(t.getApplyCode());
            storeRecord.setStorage_time(new Date());
            storeRecord.setCheckOpinion(tc.getResult());
            storeRecord.setRemark(null);
            storeRecord.setReplaceId(null);
            storeRecord.setAsseStoreId(store.getId());
            storeRecordRepository.save(storeRecord);
            // 转序单记录出入库记录主键，冲单时使用
            t.setRecordId(storeRecord.getId());
            transSheetRepository.save(t);
        }
        cur.setRouteDate(new Date());// 最终转序时间
        assemblyRouteRepository.save(cur);
        transCheckRepository.save(tc);

        /**20210608 会议讨论 会议人员：徐一贺、陈欣、李青雨、马超、王松刚
         * 1.如果生产令下所有工艺卡都已经装配完成时，回写生产令任务装配状态为已完成
         * 2.如果生产令下生产、装配、安装任务都完成时，回写生产令生产完成状态及完成时间
         * **/
        if ("转储".equals(next.getRoute()) && next.getStatus().compareTo(4) == 0) {
            // 取得机械和流体未完成工艺卡装配数
            int jlCount = testingMapper.getJxLtNotTranCompCount(sheet.getProdNo(), sheet.getId());
            if (jlCount == 0) {
                // 更新生产令装配任务状态
                ProdTasModel prodTas = new ProdTasModel();
                prodTas.setProdNo(sheet.getProdNo());
                prodTas.setProtSta(3);//任务状态：1=未开始，2=执行中，3=已完成
                prodTas.setProtDat(new Date());// 状态反写时间
                prodTas.setProtDepId(ShiroUtils.getUser().getDeptId());// 状态反写部门
                prodTas.setProtEndDat(new Date());// 结束时间
                testingMapper.updateProdTasProtStaByProdNo(prodTas);
                // 更新生产令生产完成状态及时间
                prodOrdService.udpCodStaAndDate(sheet.getProdNo(), 2);
            } else {
                // 更新生产令装配任务开始时间及状态
                ProdTasModel prodTas = new ProdTasModel();
                prodTas.setProdNo(sheet.getProdNo());
                prodTas.setProtSta(2);//任务状态：1=未开始，2=执行中，3=已完成
                prodTas.setProtDat(new Date());// 状态反写时间
                prodTas.setProtDepId(ShiroUtils.getUser().getDeptId());// 状态反写部门
                prodTas.setProtStaDat(new Date());// 开始时间
                testingMapper.updateProdTasStartProtStaByProdNo(prodTas);
            }
        } else {
            // 更新生产令装配任务开始时间及状态
            ProdTasModel prodTas = new ProdTasModel();
            prodTas.setProdNo(sheet.getProdNo());
            prodTas.setProtSta(2);//任务状态：1=未开始，2=执行中，3=已完成
            prodTas.setProtDat(new Date());// 状态反写时间
            prodTas.setProtDepId(ShiroUtils.getUser().getDeptId());// 状态反写部门
            prodTas.setProtStaDat(new Date());// 开始时间
            testingMapper.updateProdTasStartProtStaByProdNo(prodTas);
        }

        logService.saveLog("派工单-质检检验合格", "转序单ID：" + t.getId() + "，生产令号：" + sheet.getProdNo()
                + "<br>项目名称：" + sheet.getProName() + "<br>类型：" + sheet.getSpecial() + "<br>部分：" + sheet.getPart()
                + "<br>装配图号：" + sheet.getDrawNo() + "<br>装配图名：" + sheet.getDrawName() + "<br>工序：" + cur.getRoute()
                + "<br>申请数量：" + t.getNum());
        return 1;
    }

    /**
     * 质检驳回/作废
     */
    @Transactional
    public int reject(Integer id, Integer status, String result) {

        // 装配转序单表 与 装配质检表 存在一一对应的关系
        AsseTransSheet t = transSheetRepository.getOne(id);
        AsseTransCheck tc = transCheckRepository.findByTransId(t.getId());
        if (tc.getStatus() != 1) {
            return 0;
        }
        User u = ShiroUtils.getUser();
        tc.setCheckCode(u.getAccount());
        tc.setCheckName(u.getName());
        tc.setCheckTime(new Date());
        tc.setCheckDept(u.getBranchName());
        tc.setStatus(status);
        tc.setReason((result == null || result.length() < 1) ? "质检不合格，驳回" : result);
        // 如果作废， sheet表添加作废数量
        AsseAssemblyRoute cur = assemblyRouteRepository.getOne(t.getRouteId());
        AsseAssemblySheet sheet = assemblySheetRepository.getOne(cur.getSheetId());
        if (status == 5) {
            sheet.setInvalid(sheet.getInvalid() + t.getNum());
            assemblySheetRepository.save(sheet);
        }
        transCheckRepository.save(tc);
        logService.saveLog("派工单-质检" + (status == 4 ? "驳回" : "作废"), "转序单ID：" + t.getId() + "，生产令号：" + sheet.getProdNo()
                + "<br>项目名称：" + sheet.getProName() + "<br>类型：" + sheet.getSpecial() + "<br>部分：" + sheet.getPart()
                + "<br>装配图号：" + sheet.getDrawNo() + "<br>装配图名：" + sheet.getDrawName() + "<br>工序：" + cur.getRoute()
                + "<br>申请数量：" + t.getNum());
        return 1;
    }

    /**
     * 派工单-历史检验列表
     *
     * @param testModel
     * @return
     */
    public List<TestModel> findHistoryTestListByQuery(TestModel testModel) {
        testModel.setCheckCode(ShiroUtils.getUser().getAccount());
        return testingMapper.findHistoryTestListByQuery(testModel);
    }

    /**
     * 撤销质检检验
     *
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int cancelTest(Integer id) {

        // 装配转序单表 与 装配质检表 存在一一对应的关系
        AsseTransSheet t = transSheetRepository.getOne(id);
        AsseTransCheck tc = transCheckRepository.findByTransId(t.getId());

        AsseAssemblyRoute cur = assemblyRouteRepository.getOne(t.getRouteId());
        AsseAssemblyRoute next = testingMapper.findNextRoute(cur);
        AsseAssemblySheet sheet = assemblySheetRepository.getOne(cur.getSheetId());

        if (tc.getStatus() == 1 || tc.getStatus() == 4 || tc.getStatus() == 5) {
            return 0;
        }
        if (tc.getStatus() == 3 && !next.getRoute().equals("转储")) {
            return 0;
        }

        // 回写 装配质检表
        tc.setCheckCode(null);
        tc.setCheckName(null);
        tc.setCheckTime(null);
        tc.setCheckDept(null);
        tc.setYield(0);
        tc.setResult(null);
        tc.setStatus(1);
        t.setRecordId(null);

        // 回写 工序审核数量
        cur.setCheckNum(cur.getCheckNum() - t.getNum());
        cur.setStatus(2);// 工序执行中

        assemblyRouteRepository.save(cur);
        transCheckRepository.save(tc);
        transSheetRepository.save(t);

        // 判断 是否是最后工序，如果最后工序‘转储’时，要删除 asse_store 成品库 数据
        if ("转储".equals(next.getRoute())) {
            next.setRecNum(0);
            next.setStatus(1);
            testingMapper.updateRouteRecNum(next);

            AsseStore asseStore = asseStoreRepository.findBySheetId(sheet.getId());
            AsseStoreRecord storeRecordP = storeRecordRepository.getOne(t.getRecordId());

            // 修改成品库对应数据
            testingMapper.udpAsseStoreBySheetId(asseStore);

            // 生产装配件入库记录(冲单)
            AsseStoreRecord storeRecordM = new AsseStoreRecord();
            BeanUtil.copy(storeRecordP, storeRecordM);
            storeRecordM.setStoreType(1);
            storeRecordM.setRecordType(2);
            storeRecordM.setStorage_time(new Date());
            storeRecordM.setReplaceId(storeRecordP.getId());
            storeRecordM.setId(null);
            storeRecordRepository.save(storeRecordM);
        }
        logService.saveLog("派工单-质检撤销", "转序单ID：" + t.getId() + "，生产令号：" + sheet.getProdNo()
                + "<br>项目名称：" + sheet.getProName() + "<br>类型：" + sheet.getSpecial() + "<br>部分：" + sheet.getPart()
                + "<br>装配图号：" + sheet.getDrawNo() + "<br>装配图名：" + sheet.getDrawName() + "<br>工序：" + cur.getRoute()
                + "<br>申请数量：" + t.getNum());
        return 1;
    }

}
